/**
 * 提纲生成服务
 * 负责AI提纲生成、优化、导出等功能
 */

import {
  Viewpoint,
  Outline,
  OutlineStyle,
  OutlineNode,
  OptimizationSuggestion,
} from '@/types/brainstorm';

interface GenerateOutlineParams {
  sessionId: string;
  selectedViewpoints: Viewpoint[];
  style: OutlineStyle;
  targetWordCount: number;
}

/**
 * 提纲生成服务类
 */
class OutlineGeneratorService {
  private baseUrl: string;

  constructor() {
    this.baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000';
  }

  /**
   * 生成提纲
   */
  async generateOutline(params: GenerateOutlineParams): Promise<Outline> {
    const { sessionId, selectedViewpoints, style, targetWordCount } = params;

    console.log('🚀 [Outline] Generating outline:', {
      sessionId,
      viewpointsCount: selectedViewpoints.length,
      style,
      targetWordCount,
    });

    try {
      const response = await fetch(`${this.baseUrl}/api/v1/brainstorm/outline/generate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          session_id: sessionId,
          viewpoints: selectedViewpoints.map((v) => ({
            perspective: v.perspective,
            core_viewpoint: v.coreViewpoint,
            arguments: v.arguments,
          })),
          style,
          target_word_count: targetWordCount,
        }),
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();
      console.log('✅ [Outline] Outline generated successfully');
      return this.transformOutlineFromAPI(data);
    } catch (error) {
      console.error('❌ [Outline] Failed to generate outline:', error);
      // 返回模拟数据
      return this.generateMockOutline(selectedViewpoints, style, targetWordCount);
    }
  }

  /**
   * 生成模拟提纲（用于演示）
   */
  private generateMockOutline(
    viewpoints: Viewpoint[],
    style: OutlineStyle,
    targetWordCount: number
  ): Outline {
    const titleSuggestions = this.generateTitleSuggestions(viewpoints, style);
    const nodes = this.generateOutlineNodes(viewpoints, style, targetWordCount);

    return {
      id: `outline-${Date.now()}`,
      sessionId: `session-${Date.now()}`,
      titleSuggestions,
      nodes,
      style,
      totalEstimatedWords: this.calculateTotalWords(nodes),
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
  }

  /**
   * 生成标题建议
   */
  private generateTitleSuggestions(viewpoints: Viewpoint[], style: OutlineStyle): string[] {
    // 从长文本中提取关键主题词
    const coreTopics = this.extractCoreTopics(viewpoints);
    const stylePrefix = this.getStylePrefix(style);

    // 根据不同风格生成差异化的标题
    const titleTemplates = this.getTitleTemplates(style);

    return titleTemplates.map(template =>
      template
        .replace('{prefix}', stylePrefix)
        .replace('{topic}', coreTopics)
    );
  }

  /**
   * 从观点中提取核心主题词
   */
  private extractCoreTopics(viewpoints: Viewpoint[]): string {
    // 合并所有观点文本
    const allText = viewpoints.map((v) => v.coreViewpoint).join(' ');

    // 提取关键词的策略：
    // 1. 如果文本很短（<20字），直接使用
    // 2. 如果包含标点，取第一个句子的核心部分
    // 3. 否则提取前15个字符

    if (allText.length <= 20) {
      return allText;
    }

    // 尝试提取第一个完整的短语或句子
    const firstSegment = allText.split(/[，。！？；]/)[0];
    if (firstSegment && firstSegment.length <= 30) {
      // 进一步提取核心词汇（去除"在"、"的"等虚词）
      return this.extractKeyPhrase(firstSegment);
    }

    // 兜底方案：提取前15个字符
    return this.extractKeyPhrase(allText.substring(0, 15)) + '...';
  }

  /**
   * 提取关键短语（去除虚词）
   */
  private extractKeyPhrase(text: string): string {
    // 常见虚词列表
    const stopWords = ['在', '的', '了', '是', '和', '与', '或', '及', '等', '将', '会', '可能', '需要'];

    // 移除虚词，保留关键词
    let result = text;
    stopWords.forEach(word => {
      result = result.replace(new RegExp(word, 'g'), '');
    });

    // 清理多余空格
    result = result.trim();

    // 如果处理后太短，返回原文本的前20字符
    if (result.length < 5) {
      return text.substring(0, 20);
    }

    return result.substring(0, 20);
  }

  /**
   * 根据风格获取标题模板
   */
  private getTitleTemplates(style: OutlineStyle): string[] {
    const templates: Record<OutlineStyle, string[]> = {
      academic: [
        '{prefix}：{topic}的深入研究',
        '{topic}：理论框架与实证分析',
        '基于{topic}的学术探讨',
        '{topic}研究综述与展望',
        '{prefix}：{topic}的多维度分析'
      ],
      news: [
        '深度｜{topic}最新进展',
        '独家：{topic}背后的真相',
        '{topic}：影响与趋势分析',
        '聚焦{topic}：专家解读',
        '{prefix}：{topic}全景观察'
      ],
      story: [
        '{topic}：一个关于变革的故事',
        '从{topic}说起：叙事与启示',
        '{topic}背后的人与事',
        '讲述{topic}：过去、现在与未来',
        '{prefix}：{topic}的故事'
      ],
      marketing: [
        '{topic}：打造竞争优势的关键',
        '如何通过{topic}实现增长',
        '{topic}营销策略完全指南',
        '{prefix}：{topic}的商业价值',
        '掌握{topic}，赢得市场'
      ],
      tutorial: [
        '{topic}实战教程',
        '从零开始学习{topic}',
        '{topic}进阶指南',
        '{prefix}：{topic}最佳实践',
        '手把手教你掌握{topic}'
      ]
    };

    return templates[style] || templates.academic;
  }

  /**
   * 获取风格前缀
   */
  private getStylePrefix(style: OutlineStyle): string {
    const prefixes: Record<OutlineStyle, string> = {
      academic: '学术研究',
      news: '深度报道',
      story: '故事解读',
      marketing: '营销洞察',
      tutorial: '实战教程',
    };
    return prefixes[style];
  }

  /**
   * 生成提纲节点
   */
  private generateOutlineNodes(
    viewpoints: Viewpoint[],
    style: OutlineStyle,
    targetWordCount: number
  ): OutlineNode[] {
    const nodes: OutlineNode[] = [];

    // 1. 引言部分
    nodes.push({
      id: `node-intro-${Date.now()}`,
      title: '引言',
      level: 1,
      order: 0,
      mainPoints: ['背景介绍', '问题提出', '文章结构说明'],
      keywords: ['背景', '问题', '框架'],
      estimatedWords: Math.round(targetWordCount * 0.1),
      status: 'pending',
    });

    // 2. 主体部分 - 基于观点生成章节
    viewpoints.forEach((viewpoint, index) => {
      const mainNode: OutlineNode = {
        id: `node-main-${index}-${Date.now()}`,
        title: viewpoint.coreViewpoint,
        level: 1,
        order: index + 1,
        mainPoints: viewpoint.arguments,
        keywords: this.extractKeywords(viewpoint.coreViewpoint),
        estimatedWords: Math.round(targetWordCount * 0.6 / viewpoints.length),
        status: 'pending',
        children: [],
      };

      // 为每个主论点生成子章节
      viewpoint.arguments.slice(0, 3).forEach((arg, argIndex) => {
        mainNode.children?.push({
          id: `node-sub-${index}-${argIndex}-${Date.now()}`,
          title: arg,
          level: 2,
          order: argIndex,
          mainPoints: [arg],
          keywords: this.extractKeywords(arg),
          estimatedWords: Math.round(mainNode.estimatedWords / 3),
          status: 'pending',
        });
      });

      nodes.push(mainNode);
    });

    // 3. 结论部分
    nodes.push({
      id: `node-conclusion-${Date.now()}`,
      title: '总结与展望',
      level: 1,
      order: viewpoints.length + 1,
      mainPoints: ['核心观点回顾', '实践建议', '未来展望'],
      keywords: ['总结', '建议', '展望'],
      estimatedWords: Math.round(targetWordCount * 0.15),
      status: 'pending',
    });

    return nodes;
  }

  /**
   * 提取关键词
   */
  private extractKeywords(text: string): string[] {
    // 改进的关键词提取算法

    // 1. 分词（按标点和空格分割）
    const segments = text.split(/[，。、；：！？\s]+/).filter((w) => w.trim().length > 0);

    // 2. 过滤虚词和助词
    const stopWords = new Set([
      '的', '了', '在', '是', '和', '与', '或', '及', '等', '将', '会',
      '可能', '需要', '进行', '通过', '使用', '包括', '具有', '存在',
      '对于', '关于', '基于', '根据'
    ]);

    // 3. 提取有意义的词汇
    const keywords = segments
      .filter(word => word.length >= 2 && !stopWords.has(word))
      .map(word => {
        // 优先提取名词性词汇（简单规则判断）
        // 技术词汇、产品名称等通常包含这些字符
        const techKeywords = ['技术', '系统', '平台', '数据', '智能', '模型', '算法', '芯片', '制造', '风险'];
        const isTechWord = techKeywords.some(key => word.includes(key));

        return {
          word,
          weight: isTechWord ? 2 : 1,  // 技术词汇权重更高
          length: word.length
        };
      })
      // 按权重和长度排序（优先选择更重要和更具体的词）
      .sort((a, b) => {
        if (a.weight !== b.weight) return b.weight - a.weight;
        return b.length - a.length;
      })
      .map(item => item.word);

    // 4. 去重并返回前3个最重要的关键词
    return [...new Set(keywords)].slice(0, 3);
  }

  /**
   * 计算总字数
   */
  private calculateTotalWords(nodes: OutlineNode[]): number {
    return nodes.reduce((total, node) => {
      let sum = total + node.estimatedWords;
      if (node.children) {
        sum += this.calculateTotalWords(node.children);
      }
      return sum;
    }, 0);
  }

  /**
   * 转换API返回的提纲数据
   */
  private transformOutlineFromAPI(data: any): Outline {
    return {
      id: data.id || `outline-${Date.now()}`,
      sessionId: data.session_id || '',
      titleSuggestions: data.title_suggestions || [],
      nodes: data.nodes || [],
      style: data.style || 'academic',
      totalEstimatedWords: data.total_estimated_words || 0,
      createdAt: data.created_at || new Date().toISOString(),
      updatedAt: data.updated_at || new Date().toISOString(),
    };
  }

  /**
   * 优化提纲
   */
  async optimizeOutline(outlineId: string): Promise<{
    suggestions: OptimizationSuggestion[];
    optimizedOutline: Outline;
  }> {
    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/brainstorm/outline/${outlineId}/optimize`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
        }
      );

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();
      return data;
    } catch (error) {
      console.error('❌ [Outline] Failed to optimize outline:', error);
      // 返回模拟优化建议
      return this.generateMockOptimization();
    }
  }

  /**
   * 生成模拟优化建议
   */
  private generateMockOptimization(): {
    suggestions: OptimizationSuggestion[];
    optimizedOutline: Outline;
  } {
    const suggestions: OptimizationSuggestion[] = [
      {
        type: 'logic',
        severity: 'medium',
        message: '章节之间的逻辑关系可以更清晰',
        suggestion: '建议在章节之间添加过渡段落',
        autoFixAvailable: false,
      },
      {
        type: 'balance',
        severity: 'low',
        message: '部分章节字数分配不均',
        suggestion: '建议调整各章节字数，使其更加平衡',
        autoFixAvailable: true,
      },
    ];

    return {
      suggestions,
      optimizedOutline: {} as Outline, // 这里应该返回优化后的提纲
    };
  }

  /**
   * 生成替代方案
   */
  async generateAlternatives(outlineId: string, count: number = 3): Promise<Outline[]> {
    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/brainstorm/outline/${outlineId}/alternatives`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ count }),
        }
      );

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();
      return data.alternatives || [];
    } catch (error) {
      console.error('❌ [Outline] Failed to generate alternatives:', error);
      return [];
    }
  }

  /**
   * 导出提纲
   */
  async exportOutline(
    outlineId: string,
    format: 'markdown' | 'docx' | 'xmind' | 'json'
  ): Promise<Blob | null> {
    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/brainstorm/outline/${outlineId}/export?format=${format}`,
        {
          method: 'GET',
        }
      );

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      return await response.blob();
    } catch (error) {
      console.error('❌ [Outline] Failed to export outline:', error);
      return null;
    }
  }

  /**
   * 导出为Markdown（本地生成）
   */
  exportAsMarkdown(outline: Outline): string {
    let markdown = `# ${outline.titleSuggestions[0] || '文章标题'}\n\n`;
    markdown += `**预计总字数**: ${outline.totalEstimatedWords}字\n\n`;
    markdown += `**风格**: ${this.getStyleName(outline.style)}\n\n`;
    markdown += `---\n\n`;

    const renderNode = (node: OutlineNode, depth: number = 0): string => {
      const prefix = '#'.repeat(depth + 2);
      let md = `${prefix} ${node.title}\n\n`;

      if (node.mainPoints && node.mainPoints.length > 0) {
        md += `**要点**:\n`;
        node.mainPoints.forEach((point) => {
          md += `- ${point}\n`;
        });
        md += '\n';
      }

      if (node.keywords && node.keywords.length > 0) {
        md += `**关键词**: ${node.keywords.join(', ')}\n\n`;
      }

      md += `**预计字数**: ${node.estimatedWords}字\n\n`;

      if (node.children && node.children.length > 0) {
        node.children.forEach((child) => {
          md += renderNode(child, depth + 1);
        });
      }

      return md;
    };

    outline.nodes.forEach((node) => {
      markdown += renderNode(node, 0);
    });

    return markdown;
  }

  /**
   * 获取风格名称
   */
  private getStyleName(style: OutlineStyle): string {
    const names: Record<OutlineStyle, string> = {
      academic: '学术论文',
      news: '新闻报道',
      story: '故事叙述',
      marketing: '营销文案',
      tutorial: '教程指南',
    };
    return names[style];
  }
}

export const outlineGeneratorService = new OutlineGeneratorService();
